home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume22 / queuer / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-06-07  |  49.4 KB

  1. Subject:  v22i008:  Multi-system program queueing package, Part02/03
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 5f0ab7c9 6a6a7236 2192d719 faf681e1
  5.  
  6. Submitted-by: Scott Bradner <sob@harvisr.harvard.edu>
  7. Posting-number: Volume 22, Issue 8
  8. Archive-name: queuer/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 2 (of 3)."
  17. # Contents:  com.c defer.c dequeue.c qrm.c queue.1 queue.c queued.5
  18. #   queued.c readconf.c selhost.c showqueue.c
  19. # Wrapped by rsalz@coconut.bbn.com on Tue May  1 17:18:26 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'com.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'com.c'\"
  23. else
  24. echo shar: Extracting \"'com.c'\" \(2927 characters\)
  25. sed "s/^X//" >'com.c' <<'END_OF_FILE'
  26. X/* Copyright 1990  The President and Fellows of Harvard University
  27. X
  28. XPermission to use, copy, modify, and distribute this program for any
  29. Xpurpose and without fee is hereby granted, provided that this
  30. Xcopyright and permission notice appear on all copies and supporting
  31. Xdocumentation, the name of Harvard University not be used in advertising
  32. Xor publicity pertaining to distribution of the program, or to results
  33. Xderived from its use, without specific prior written permission, and notice
  34. Xbe given in supporting documentation that copying and distribution is by
  35. Xpermission of Harvard University.  Harvard University makes no
  36. Xrepresentations about the suitability of this software for any purpose.
  37. XIt is provided "as is" without express or implied warranty.    */
  38. X
  39. X/* com.c - Dan Lanciani '85 */
  40. X
  41. X#include <sgtty.h>
  42. X#include <stdio.h>
  43. X#include <signal.h>
  44. X
  45. X#include "queue.h"
  46. X
  47. Xint tolduser;
  48. X
  49. Xcom(s, se)
  50. X{
  51. X    char buf[BUFSIZ];
  52. X    register int cnt;
  53. X
  54. X    switch(mode) {
  55. X
  56. X        case QM_BATCH:
  57. X            if(!tolduser)
  58. X                fprintf(stderr, "Job queued.\n");
  59. X            break;
  60. X
  61. X        case QM_BACKGROUND:
  62. X            if(se < 0)
  63. X                while((cnt = read(s, buf, BUFSIZ)) > 0)
  64. X                    write(1, buf, cnt);
  65. X            else
  66. X                modem(s, se, -1, 1, 2);
  67. X            break;
  68. X
  69. X        case QM_INTERACTIVE:
  70. X            modem(s, se, 0, 1, 2);
  71. X            break;
  72. X
  73. X        default:
  74. X            fprintf(stderr, "Bad mode (%d)\n", mode);
  75. X            break;
  76. X    }
  77. X}
  78. X
  79. Xstatic long tmask, emask;
  80. X
  81. Xmodem(s, se, i, o, e)
  82. X{
  83. X    long isample, osample;
  84. X    register int scnt, secnt, tcnt;
  85. X    int t, on = 1;
  86. X    char sbuf[BUFSIZ], sebuf[BUFSIZ], tbuf[BUFSIZ];
  87. X    register char *sp, *sep, *tp;
  88. X
  89. X    ioctl(s, FIONBIO, &on);
  90. X    scnt = secnt = tcnt = 0;
  91. X    sp = sbuf;
  92. X    sep = sebuf;
  93. X    tp = tbuf;
  94. X    if(i < 0)
  95. X        tmask = 0;
  96. X    else
  97. X        tmask = (1L<<i);
  98. X    emask = (1L<<se);
  99. X    while(1) {
  100. X        isample = osample = 0;
  101. X        if(scnt)
  102. X            osample |= (1L<<o);
  103. X        else
  104. X            isample |= (1L<<s);
  105. X        if(secnt)
  106. X            osample |= (1L<<e);
  107. X        else
  108. X            isample |= emask;
  109. X        if(tcnt)
  110. X            osample |= (1L<<s);
  111. X        else
  112. X            isample |= tmask;
  113. X        if(select(32, &isample, &osample, 0, 0) <= 0)
  114. X            continue;
  115. X        if(isample & (1L<<s))
  116. X            if((scnt = read(s, sbuf, BUFSIZ)) <= 0) {
  117. X                if(scnt < 0)
  118. X                    break;
  119. X                close(o);
  120. X                break;
  121. X            }
  122. X            else
  123. X                sp = sbuf;
  124. X        if(isample & (1L<<se))
  125. X            if((secnt = read(se, sebuf, BUFSIZ)) <= 0) {
  126. X                if(secnt < 0)
  127. X                    break;
  128. X                close(e);
  129. X                emask = 0;
  130. X            }
  131. X            else
  132. X                sep = sebuf;
  133. X        if(isample & tmask) {
  134. X            if(isatty(i)) {
  135. X                ioctl(i, TIOCGPGRP, &t);
  136. X                if(t != getpgrp(getpid())) {
  137. X                    shutdown(s, 1);
  138. X                    tmask = 0;
  139. X                    continue;
  140. X                }
  141. X            }
  142. X            if((tcnt = read(i, tbuf, BUFSIZ)) <= 0) {
  143. X                if(tcnt < 0)
  144. X                    break;
  145. X                shutdown(s, 1);
  146. X                tmask = 0;
  147. X            }
  148. X            else
  149. X                tp = tbuf;
  150. X        }
  151. X        if(osample & (1L<<s)) {
  152. X            t = write(s, tp, tcnt);
  153. X                if(t < 0)
  154. X                    break;
  155. X            tcnt -= t;
  156. X            tp += t;
  157. X        }
  158. X        if(osample & (1L<<e)) {
  159. X            t = write(e, sep, secnt);
  160. X                if(t < 0)
  161. X                    break;
  162. X            secnt -= t;
  163. X            sep += t;
  164. X        }
  165. X        if(osample & (1L<<o)) {
  166. X            t = write(o, sp, scnt);
  167. X                if(t < 0)
  168. X                    break;
  169. X            scnt -= t;
  170. X            sp += t;
  171. X        }
  172. X    }
  173. X}
  174. END_OF_FILE
  175. if test 2927 -ne `wc -c <'com.c'`; then
  176.     echo shar: \"'com.c'\" unpacked with wrong size!
  177. fi
  178. # end of 'com.c'
  179. fi
  180. if test -f 'defer.c' -a "${1}" != "-c" ; then 
  181.   echo shar: Will not clobber existing file \"'defer.c'\"
  182. else
  183. echo shar: Extracting \"'defer.c'\" \(3845 characters\)
  184. sed "s/^X//" >'defer.c' <<'END_OF_FILE'
  185. X/* Copyright 1990  The President and Fellows of Harvard University
  186. X
  187. XPermission to use, copy, modify, and distribute this program for any
  188. Xpurpose and without fee is hereby granted, provided that this
  189. Xcopyright and permission notice appear on all copies and supporting
  190. Xdocumentation, the name of Harvard University not be used in advertising
  191. Xor publicity pertaining to distribution of the program, or to results
  192. Xderived from its use, without specific prior written permission, and notice
  193. Xbe given in supporting documentation that copying and distribution is by
  194. Xpermission of Harvard University.  Harvard University makes no
  195. Xrepresentations about the suitability of this software for any purpose.
  196. XIt is provided "as is" without express or implied warranty.    */
  197. X
  198. X
  199. X/* defer.c - Dan Lanciani '85 */
  200. X
  201. X#include <sys/param.h>
  202. X#include <pwd.h>
  203. X#include <grp.h>
  204. X#include <stdio.h>
  205. X
  206. Xchar *getenv(), *index(), *rindex(), *malloc();
  207. XFILE *popen();
  208. Xstruct passwd *getpwuid();
  209. Xstruct group *getgrgid();
  210. X
  211. Xmain(argc, argv)
  212. Xchar **argv;
  213. X{
  214. X    register int i, ng;
  215. X    gid_t groups[NGROUPS];
  216. X    char buf[BUFSIZ], buf1[BUFSIZ], user[30];
  217. X    register char *p;
  218. X    FILE *n, *popen();
  219. X    register struct passwd *pw;
  220. X    register struct group *gr;
  221. X
  222. X    if((i = getgid()) != getegid()) {
  223. X        if(!(gr = getgrgid(i))) {
  224. X            fprintf(stderr, "What group are you?\n");
  225. X            exit(1);
  226. X        }
  227. X        setenv("GROUP=", gr->gr_name);
  228. X    }
  229. X    ng = getgroups(NGROUPS, groups);
  230. X    setgid(getegid());
  231. X    setgroups(ng, groups);
  232. X    setuid(i = getuid());
  233. X    if(!(pw = getpwuid(i))) {
  234. X        fprintf(stderr, "Who are you?\n");
  235. X        exit(1);
  236. X    }
  237. X    strcpy(user, pw->pw_name);
  238. X    strcat(user, "\t");
  239. X    ng = strlen(user);
  240. X    if(p = rindex(argv[0], '/'))
  241. X        argv[0] = p + 1;
  242. X    for(i = 1; i < argc && argv[i][0] == '-'; i++)
  243. X        setenv("QNOTIFY=", &argv[i][1]);
  244. X    if(argc == i) {
  245. X        printf("Enter command:\n");
  246. X        gets(buf);
  247. X    }
  248. X    else {
  249. X        buf[0] = '\0';
  250. X        for(; i < argc; i++) {
  251. X            strcat(buf, argv[i]);
  252. X            if(i < argc - 1)
  253. X                strcat(buf, " ");
  254. X        }
  255. X    }
  256. X    if(strcmp(argv[0], "defer.long")) {
  257. X        if(n = popen("exec /usr/local/bin/qs bsh", "r")) {
  258. X            i = 0;
  259. X            while(fgets(p = buf1, sizeof(buf1), n)) {    
  260. X                if(!(p = index(p, '\t')))
  261. X                    continue;
  262. X                if(!(p = index(p + 1, '\t')))
  263. X                    continue;
  264. X                if(!strncmp(p + 1, user, ng))
  265. X                    i++;
  266. X            }
  267. X            pclose(n);
  268. X            if(i > 2) {
  269. X                fprintf(stderr, "You have 3 queued already\n");
  270. X                exit(1);
  271. X            }
  272. X        }
  273. X        if((p = getenv("SHELL")) && !strcmp(p, "/bin/csh"))
  274. X            execl("/usr/queued_pgms/bcsh", "bcsh", "-c", buf, 0);
  275. X        else
  276. X            execl("/usr/queued_pgms/bsh", "bsh", "-c", buf, 0);
  277. X    }
  278. X    else {
  279. X        if(n = popen("exec /usr/local/bin/qs bsh.long", "r")) {
  280. X            i = 0;
  281. X            while(fgets(p = buf1, sizeof(buf1), n)) {    
  282. X                if(!(p = index(p, '\t')))
  283. X                    continue;
  284. X                if(!(p = index(p + 1, '\t')))
  285. X                    continue;
  286. X                if(!strncmp(p + 1, user, ng))
  287. X                    i++;
  288. X            }
  289. X            pclose(n);
  290. X            if(i > 2) {
  291. X                fprintf(stderr, "You have 3 queued already\n");
  292. X                exit(1);
  293. X            }
  294. X        }
  295. X        if((p = getenv("SHELL")) && !strcmp(p, "/bin/csh"))
  296. X            execl("/usr/queued_pgms/bcsh","bcsh.long","-c", buf, 0);
  297. X        else
  298. X            execl("/usr/queued_pgms/bsh", "bsh.long", "-c", buf, 0);
  299. X    }
  300. X    fprintf(stderr, "Can't find queuer?!?\n");
  301. X    exit(1);
  302. X}
  303. X
  304. Xsetenv(var, value)
  305. Xchar *var, *value;
  306. X{
  307. X    extern char **environ;
  308. X    char **envnew;
  309. X    int i;
  310. X    int varlen = strlen(var);
  311. X    int vallen = strlen(value);
  312. X    static first = 1;
  313. X
  314. X    if(first) {
  315. X        first = 0;
  316. X        i = 0;
  317. X        while(environ[i])
  318. X            i++;
  319. X        envnew = (char **) malloc(sizeof (char *) * (i + 1));
  320. X        for(; i >= 0; i--)
  321. X            envnew[i] = environ[i];
  322. X        environ = envnew;
  323. X    }
  324. X    for(i = 0; environ[i]; i++) {
  325. X        if (strncmp(environ[i], var, varlen) == 0) {
  326. X            environ[i] = malloc(varlen + vallen + 1);
  327. X            strcpy(environ[i], var);
  328. X            strcat(environ[i], value);
  329. X            return;
  330. X        }
  331. X    }
  332. X    environ = (char **) realloc(environ, sizeof (char *) * (i + 2));
  333. X    environ[i] = malloc(varlen + vallen + 1);
  334. X    strcpy(environ[i], var);
  335. X    strcat(environ[i], value);
  336. X    environ[++i] = 0;
  337. X}
  338. END_OF_FILE
  339. if test 3845 -ne `wc -c <'defer.c'`; then
  340.     echo shar: \"'defer.c'\" unpacked with wrong size!
  341. fi
  342. # end of 'defer.c'
  343. fi
  344. if test -f 'dequeue.c' -a "${1}" != "-c" ; then 
  345.   echo shar: Will not clobber existing file \"'dequeue.c'\"
  346. else
  347. echo shar: Extracting \"'dequeue.c'\" \(2408 characters\)
  348. sed "s/^X//" >'dequeue.c' <<'END_OF_FILE'
  349. X/* Copyright 1990  The President and Fellows of Harvard University
  350. X
  351. XPermission to use, copy, modify, and distribute this program for any
  352. Xpurpose and without fee is hereby granted, provided that this
  353. Xcopyright and permission notice appear on all copies and supporting
  354. Xdocumentation, the name of Harvard University not be used in advertising
  355. Xor publicity pertaining to distribution of the program, or to results
  356. Xderived from its use, without specific prior written permission, and notice
  357. Xbe given in supporting documentation that copying and distribution is by
  358. Xpermission of Harvard University.  Harvard University makes no
  359. Xrepresentations about the suitability of this software for any purpose.
  360. XIt is provided "as is" without express or implied warranty.    */
  361. X
  362. X
  363. X/* dequeue.c - Dan Lanciani '85 */
  364. X
  365. X#include <stdio.h>
  366. X#include <signal.h>
  367. X
  368. X#include "queue.h"
  369. X
  370. Xdequeue(s)
  371. X{
  372. X    char buf[BUFSIZ], what[BUFSIZ], prog[BUFSIZ], user[BUFSIZ];
  373. X    register FILE *n, *m;
  374. X    register int i, t, k;
  375. X    register long c, u;
  376. X
  377. X    for(i = 0; i < 3; i++)
  378. X        dup2(s, i);
  379. X    getstr(s, user);
  380. X    getstr(s, prog);
  381. X    getstr(s, what);
  382. X    if(strcmp(what, "all"))
  383. X        c = atol(what);
  384. X    else
  385. X        c = -1;
  386. X    if(isunid(c)) {
  387. X        sprintf(buf, "%s/%ld", SPOOLDIR, c);
  388. X        if(!(n = fopen(buf, "r")))
  389. X            exit(0);
  390. X        fgetstr(n, buf);
  391. X        fclose(n);
  392. X        if(!(c = atoi(buf)))
  393. X            exit(0);
  394. X    }
  395. X    if(i = readconf(prog)) {
  396. X        fprintf(stderr, "Unknown remote configuration (%d)\n", i);
  397. X        exit(1);
  398. X    }
  399. X    sprintf(buf, "%s/%s", SPOOLDIR, queue);
  400. X    if(!(n = fopen(buf, "r"))) {
  401. X        fprintf(stderr, "Queue file missing\n");
  402. X        exit(1);
  403. X    }
  404. X    while(fgets(buf, sizeof(buf), n))
  405. X        if(c == (k = atoi(buf)) || !c || c == -1) {
  406. X            sprintf(buf, "%s/%d", SPOOLDIR, k);
  407. X            if(!(m = fopen(buf, "r"))) {
  408. X                fprintf(stderr, "Spool file missing (%d)\n", k);
  409. X                continue;
  410. X            }
  411. X            fgetstr(m, buf);
  412. X            fgetstr(m, buf);
  413. X            u = atol(buf);
  414. X            fgetstr(m, buf);
  415. X            t = atoi(buf);
  416. X            for(i = 0; i < t; i++)
  417. X                fgetstr(m, buf);
  418. X            fgetstr(m, buf);
  419. X            if(!c && strcmp(buf, what)) {
  420. X                fclose(m);
  421. X                continue;
  422. X            }
  423. X            if(strcmp(buf, user) && strcmp(user, "root")) {
  424. X                if(u)
  425. X                fprintf(stderr, "Not owner (%s, %ld)\n", buf,u);
  426. X                else
  427. X                fprintf(stderr, "Not owner (%s, %d)\n", buf, k);
  428. X                fclose(m);
  429. X                continue;
  430. X            }
  431. X            kill(k, SIGTERM);
  432. X            if(u)
  433. X            fprintf(stderr, "Killed %ld of %s for %s\n",u,buf,user);
  434. X            else
  435. X            fprintf(stderr, "Killed %d of %s for %s\n", k,buf,user);
  436. X            fclose(m);
  437. X        }
  438. X    fclose(n);
  439. X    exit(0);
  440. X}
  441. END_OF_FILE
  442. if test 2408 -ne `wc -c <'dequeue.c'`; then
  443.     echo shar: \"'dequeue.c'\" unpacked with wrong size!
  444. fi
  445. # end of 'dequeue.c'
  446. fi
  447. if test -f 'qrm.c' -a "${1}" != "-c" ; then 
  448.   echo shar: Will not clobber existing file \"'qrm.c'\"
  449. else
  450. echo shar: Extracting \"'qrm.c'\" \(2489 characters\)
  451. sed "s/^X//" >'qrm.c' <<'END_OF_FILE'
  452. X/* Copyright 1990  The President and Fellows of Harvard University
  453. X
  454. XPermission to use, copy, modify, and distribute this program for any
  455. Xpurpose and without fee is hereby granted, provided that this
  456. Xcopyright and permission notice appear on all copies and supporting
  457. Xdocumentation, the name of Harvard University not be used in advertising
  458. Xor publicity pertaining to distribution of the program, or to results
  459. Xderived from its use, without specific prior written permission, and notice
  460. Xbe given in supporting documentation that copying and distribution is by
  461. Xpermission of Harvard University.  Harvard University makes no
  462. Xrepresentations about the suitability of this software for any purpose.
  463. XIt is provided "as is" without express or implied warranty.    */
  464. X
  465. X
  466. X/* qrm.c - Dan Lanciani '85 */
  467. X
  468. X#include <stdio.h>
  469. X#include <errno.h>
  470. X#include <sys/types.h>
  471. X#include <sys/socket.h>
  472. X#include <netinet/in.h>
  473. X#include <netdb.h>
  474. X#include <pwd.h>
  475. X
  476. X#include "queue.h"
  477. X
  478. Xextern int errno;
  479. Xstruct servent *sp;
  480. X
  481. Xmain(argc, argv)
  482. Xchar **argv;
  483. X{
  484. X    register struct passwd *pw;
  485. X    register int i, error = 0;
  486. X
  487. X    if(argc != 3) {
  488. X        fprintf(stderr, "Usage: %s command pid\n", argv[0]);
  489. X        exit(1);
  490. X    }
  491. X    if(!(pw = getpwuid(getuid()))) {
  492. X        fprintf(stderr, "Who are you?\n");
  493. X        exit(1);
  494. X    }
  495. X    if(i = readconf(argv[1])) {
  496. X        fprintf(stderr, "Unknown configuration (%d)\n", i);
  497. X        exit(1);
  498. X    }
  499. X    if(*qm && (sp = getservbyname("qmaster", "tcp")))
  500. X        delq(qm, pw->pw_name, argv[1], argv[2]);
  501. X    if(!(sp = getservbyname("queue", "tcp"))) {
  502. X        fprintf(stderr, "queue: Bad service?!?\n");
  503. X        exit(1);
  504. X    }
  505. X    for(i = 0; i < hcnt; i++)
  506. X        error |= delq(hosts[i], pw->pw_name, argv[1], argv[2]);
  507. X    if(error) {
  508. X        gethostname(host, sizeof(host));
  509. X        delq(host, pw->pw_name, argv[1], argv[2]);
  510. X    }
  511. X}
  512. X
  513. Xdelq(h, u, p, n)
  514. Xregister char *h, *u, *p, *n;
  515. X{
  516. X    struct sockaddr_in sin;
  517. X    register struct hostent *hp;
  518. X    int s, trys, i;
  519. X
  520. X    if(!(hp = gethostbyname(h))) {
  521. X        fprintf(stderr, "%s: Unknown host?!?\n", h);
  522. X        return(1);
  523. X    }
  524. X    trys = 0;
  525. X    i = IPPORT_RESERVED - 1;
  526. Xretry:
  527. X    if((s = rresvport(&i)) < 0) {
  528. X        perror("rresvport");
  529. X        return(1);
  530. X    }
  531. X    sin.sin_family = hp->h_addrtype;
  532. X    sin.sin_port = sp->s_port;
  533. X    bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
  534. X    if(connect(s, &sin, sizeof(sin))) {
  535. X        close(s);
  536. X        if(trys++ < 5) {
  537. X            sleep(trys);
  538. X            i--;
  539. X            goto retry;
  540. X        }
  541. X        perror("connect");
  542. X        return(1);
  543. X    }
  544. X    write(s, "\2", 1);
  545. X    write(s, u, strlen(u)+1);
  546. X    write(s, p, strlen(p)+1);
  547. X    write(s, n, strlen(n)+1);
  548. X    mode = QM_BACKGROUND;
  549. X    com(s, -1);
  550. X    close(s);
  551. X    return(0);
  552. X}
  553. END_OF_FILE
  554. if test 2489 -ne `wc -c <'qrm.c'`; then
  555.     echo shar: \"'qrm.c'\" unpacked with wrong size!
  556. fi
  557. # end of 'qrm.c'
  558. fi
  559. if test -f 'queue.1' -a "${1}" != "-c" ; then 
  560.   echo shar: Will not clobber existing file \"'queue.1'\"
  561. else
  562. echo shar: Extracting \"'queue.1'\" \(3326 characters\)
  563. sed "s/^X//" >'queue.1' <<'END_OF_FILE'
  564. X.TH QUEUE 1 "11 September 1985"
  565. X.UC 4
  566. X.SH NAME
  567. Xqueue  \- transparently queue processes for remote or local execution
  568. X.SH SYNOPSIS
  569. X.nf
  570. Xln queue ``program''
  571. X``program''
  572. X.fi
  573. X.PP
  574. X.SH DESCRIPTION
  575. X.I Queue
  576. Xis never invoked directly, but is always linked to a program that is to
  577. Xbe queued.  The actions taken by
  578. X.B queue
  579. Xare controlled by the name with which it is invoked and by a configuration
  580. Xfile associated with that name.  The configuration file is generally set
  581. Xup to transparently emulate the program which
  582. X.B queue
  583. Xreplaces.
  584. X.PP
  585. XIn all cases, 
  586. X.B queue
  587. Xcreates a virtual connection to an instance of the queued(8) daemon which
  588. Xperforms the actual operation.  The daemon may reside on the local host
  589. Xor on another host which can be reached through the internet.  Necessary
  590. Xfiles (arguments) will be supplied to the daemon and output will be
  591. Xreturned to the user of
  592. X.B queue.
  593. X.PP
  594. XPrograms run by
  595. X.B queue
  596. Xinherit the environment of the invoker, even if the actual execution
  597. Xtakes place on a remote host.  Moreover, certain characteristics may
  598. Xbe controlled by setting predefined environment variables.
  599. X.PP
  600. XThe
  601. X.B QMAXCPU
  602. Xenvironment variable places a (lower) ceiling on the number of CPU
  603. Xseconds that a process may consume.  It is useful to prevent runaway
  604. Xprocesses from using up excessive resources.  In no event can the
  605. X.B QMAXCPU
  606. Xvariable be used to increase the the cpu time beyond that set in the
  607. Xprogram's queued configuration file.  Similarly, the
  608. X.B QMAXTIME
  609. Xenvironment variable places a ceiling on the number of real seconds for
  610. Xwhich a process may run.  This is useful in cases where processes
  611. Xcould become ``hung,'' accruing no CPU time but blocking the queue.
  612. X.PP
  613. XThe
  614. X.B QMINNICE
  615. Xenvironment variable alters the base nice (scheduling priority).  Increasing
  616. Xthis variable causes the process to receive a smaller percent of the
  617. Xcpu resource per unit time.  A high ``nice'' should be used for long-running,
  618. Xnon-time-critical jobs to avoid slowing down the system for interactive users.
  619. XThe
  620. X.B QMINNICE
  621. Xvariable cannot be used to lower the ``nice'' below the value specified
  622. Xin the program's queued configuration file.
  623. X.PP
  624. XThe
  625. X.B QNOTIFY
  626. Xvariable sets the method of notification upon completion of batch jobs.
  627. XIt may be set to "mail" for mail only, to "send" for terminal messages
  628. Xonly, to "saml" for both, to "soml" for mail only in the event that
  629. Xterminal messages cannot be delivered, and to "none" for no special
  630. Xnotification.  If not set,
  631. X.B QNOTIFY
  632. Xdefaults to "mail."  Note that in all cases any errors generated by
  633. Xthe job will be mailed and that the additional informational mailing
  634. Xwill be suppressed in these cases.
  635. X.SH "FILES (/usr/lib/queued/)"
  636. XQUEUES        list of active, local queues
  637. X.br
  638. X``program''    configuration file for ``program''
  639. X.SH "FILES (/usr/spool/queued/)"
  640. XLOCK            master lock node
  641. X.br
  642. X``queue''        current information for ``queue''
  643. X.br
  644. X``queue''.lock    lock on ``queue''
  645. X.br
  646. X``queue''.tmp    used for rewriting ``queue''
  647. X.br
  648. X``pid''        current information for ``pid''
  649. X.br
  650. X``pid''.dir    temporary execution directory
  651. X.br
  652. X``pid''.batch    output of batch execution process
  653. X.SH "FILES (Other)"
  654. X/usr/adm/qacct    queue accounting file
  655. X.br
  656. X/etc/hosts.efs    hosts with extended file system
  657. X.br
  658. X/etc/hosts.flat    hosts with one-to-one uid mapping
  659. X.SH "SEE ALSO"
  660. Xqrm(1), qs(1), queued(5), queued(8)
  661. X.SH AUTHOR
  662. XDan Lanciani
  663. END_OF_FILE
  664. if test 3326 -ne `wc -c <'queue.1'`; then
  665.     echo shar: \"'queue.1'\" unpacked with wrong size!
  666. fi
  667. # end of 'queue.1'
  668. fi
  669. if test -f 'queue.c' -a "${1}" != "-c" ; then 
  670.   echo shar: Will not clobber existing file \"'queue.c'\"
  671. else
  672. echo shar: Extracting \"'queue.c'\" \(6647 characters\)
  673. sed "s/^X//" >'queue.c' <<'END_OF_FILE'
  674. X/* Copyright 1990  The President and Fellows of Harvard University
  675. X
  676. XPermission to use, copy, modify, and distribute this program for any
  677. Xpurpose and without fee is hereby granted, provided that this
  678. Xcopyright and permission notice appear on all copies and supporting
  679. Xdocumentation, the name of Harvard University not be used in advertising
  680. Xor publicity pertaining to distribution of the program, or to results
  681. Xderived from its use, without specific prior written permission, and notice
  682. Xbe given in supporting documentation that copying and distribution is by
  683. Xpermission of Harvard University.  Harvard University makes no
  684. Xrepresentations about the suitability of this software for any purpose.
  685. XIt is provided "as is" without express or implied warranty.    */
  686. X
  687. X
  688. X/* queue.c - Dan Lanciani '85 */
  689. X
  690. X#include <stdio.h>
  691. X#include <errno.h>
  692. X#include <sys/param.h>
  693. X#include <sys/stat.h>
  694. X#include <sys/socket.h>
  695. X#include <netinet/in.h>
  696. X#include <netdb.h>
  697. X#include <pwd.h>
  698. X#include <grp.h>
  699. X#include <signal.h>
  700. X
  701. X#include "queue.h"
  702. X
  703. Xextern int errno, botch();
  704. Xstruct servent *sp;
  705. Xstruct passwd *pw;
  706. Xstruct group *gr;
  707. Xstruct sockaddr_in sin;
  708. Xlong unid;
  709. X
  710. Xmain(argc, argv, envp)
  711. Xchar **argv, **envp;
  712. X{
  713. X    register struct optent *p, *op;
  714. X    struct stat statb;
  715. X    register FILE *n;
  716. X    char wd[BUFSIZ], buf[BUFSIZ];
  717. X    int i, s, se = -1, ng, fd, local = 1;
  718. X    gid_t groups[NGROUPS];
  719. X
  720. X    while((i = open("/dev/null", 2)) < 3);
  721. X    close(i);
  722. X    if(argc < 1) {
  723. X        fprintf(stderr, "No arguments?\n");
  724. X        exit(1);
  725. X    }
  726. X    if(rindex(argv[0], '/'))
  727. X        argv[0] = rindex(argv[0], '/') + 1;
  728. X    if(!(pw = getpwuid(getuid())) || !(gr = getgrgid(getgid()))) {
  729. X        fprintf(stderr, "Who are you?\n");
  730. X        exit(1);
  731. X    }
  732. X    if(!getwd(wd)) {
  733. X        fprintf(stderr, "Can't get current directory\n");
  734. X        exit(1);
  735. X    }
  736. X    if(i = readconf(argv[0])) {
  737. X        fprintf(stderr, "Unknown configuration (%d)\n", i);
  738. X        exit(1);
  739. X    }
  740. X    for(i = 1; i < argc; i++) {
  741. X        op = NULL;
  742. X        for(p = option; p; p = p->op_next) {
  743. X            if(optcmp(p->op_name, argv[i])) {
  744. X                op = p;
  745. X                break;
  746. X            }
  747. X            if(!strcmp(p->op_name, "DEFAULT"))
  748. X                op = p;
  749. X        }
  750. X        if(!op) {
  751. X            fprintf(stderr, "Unknown option (%s)\n", argv[i]);
  752. X            exit(1);
  753. X        }
  754. X        switch(op->op_action) {
  755. X
  756. X        case OPA_IGNORE:
  757. X            if(!strcmp(op->op_arg, "ARG1"))
  758. X                i++;
  759. X            break;
  760. X
  761. X        case OPA_COPYIN:
  762. X            p = (struct optent *)malloc(sizeof(struct optent));
  763. X            *p = *op;
  764. X            if(!strcmp(p->op_arg, "ARG0"))
  765. X                p->op_arg = newstring(argv[i]);
  766. X            else if(!strcmp(p->op_arg, "ARG1"))
  767. X                p->op_arg = newstring(argv[++i]);
  768. X            p->op_next = copyin;
  769. X            copyin = p;
  770. X            break;
  771. X
  772. X        case OPA_COPYOUT:
  773. X            p = (struct optent *)malloc(sizeof(struct optent));
  774. X            *p = *op;
  775. X            if(!strcmp(p->op_arg, "ARG0"))
  776. X                p->op_arg = newstring(argv[i]);
  777. X            else if(!strcmp(p->op_arg, "ARG1"))
  778. X                p->op_arg = newstring(argv[++i]);
  779. X            p->op_next = copyout;
  780. X            copyout = p;
  781. X            break;
  782. X
  783. X        default:
  784. X            fprintf(stderr, "Bad action (%d)\n", op->op_action);
  785. X            exit(1);
  786. X        }
  787. X    }
  788. X    selhost(argc, argv);
  789. X    if(!(sp = getservbyname("queue", "tcp"))) {
  790. X        fprintf(stderr, "queue: Bad service?!?\n");
  791. X        exit(1);
  792. X    }
  793. X    for(i = 0; i < hcnt; i++)
  794. X        if((s = qconnect(hosts[i])) >= 0) {
  795. X            strcpy(host, hosts[i]);
  796. X            goto found;
  797. X        }
  798. X    if(nolocal) {
  799. X        fprintf(stderr, "No authorized host available\n");
  800. X        fprintf(stderr, "Please contact a staff person.\n");
  801. X        exit(1);
  802. X    }
  803. X    gethostname(host, sizeof(host));
  804. X    if((s = qconnect(host)) < 0) {
  805. X        fprintf(stderr, "Running locally\n");
  806. X        cspawn(prog, argv);
  807. X        wait(0);
  808. X        exit(0);
  809. X    }
  810. Xfound:
  811. X    gethostname(buf, BUFSIZ);
  812. X    if(strcmp(host, buf) && strcmp(host, "localhost"))
  813. X        local = 0;
  814. X    if(mode == QM_INTERACTIVE) {
  815. X        i = IPPORT_RESERVED - 2;
  816. X        if((se = rresvport(&i)) < 0) {
  817. X            perror("rresvport");
  818. X            exit(1);
  819. X        }
  820. X        listen(se, 1);
  821. X    }
  822. X    else
  823. X        i = 0;
  824. X    setuid(getuid());
  825. X    if(!(n = fdopen(s, "w"))) {
  826. X        perror("fdopen");
  827. X        exit(1);
  828. X    }
  829. X    putc(0, n);
  830. X    fprintf(n, "%d", i);
  831. X    putc('\0', n);
  832. X    fflush(n);
  833. X    if(i) {
  834. X        int fromlen = sizeof(struct sockaddr_in);
  835. X        struct sockaddr_in from;
  836. X        signal(SIGALRM, botch);
  837. X        alarm(30);
  838. X        if((i = accept(se, &from, &fromlen)) < 0) {
  839. X            perror("accept");
  840. X            exit(1);
  841. X        }
  842. X        alarm(0);
  843. X        signal(SIGALRM, SIG_DFL);
  844. X        close(se);
  845. X        se = i;
  846. X        if(ntohs((u_short)from.sin_port) >= IPPORT_RESERVED) {
  847. X            fprintf(stderr, "Protocol failed\n");
  848. X            exit(1);
  849. X        }
  850. X    }
  851. X    fprintf(n, "%ld", unid);
  852. X    putc('\0', n);
  853. X    fprintf(n, "%d", argc);
  854. X    putc('\0', n);
  855. X    for(i = 0; i < argc; i++)
  856. X        xfputs(argv[i], n);
  857. X    xfputs(pw->pw_name, n);
  858. X    xfputs(gr->gr_name, n);
  859. X    ng = getgroups(NGROUPS, groups);
  860. X    fprintf(n, "%d", ng);
  861. X    putc('\0', n);
  862. X    for(i = 0; i < ng; i++)
  863. X        if(gr = getgrgid(groups[i]))
  864. X            xfputs(gr->gr_name, n);
  865. X        else {
  866. X            fprintf(stderr, "Who are you (groups)?\n");
  867. X            exit(1);
  868. X        }
  869. X    xfputs(wd, n);
  870. X    for(ng = 0; envp[ng]; ng++);
  871. X    fprintf(n, "%d", ng);
  872. X    putc('\0', n);
  873. X    for(i = 0; i < ng; i++)
  874. X        xfputs(envp[i], n);
  875. X    if(!local) {
  876. X        if(efs && infile(EFSFILE, host)) {
  877. X            xfputs("efs", n);
  878. X            i = 0;
  879. X            for(p = copyout; p; p = p->op_next)
  880. X                i++;
  881. X            for(p = copyin; p; p = p->op_next)
  882. X                i++;
  883. X            fprintf(n, "%d", i);
  884. X            putc('\0', n);
  885. X            for(p = copyout; p; p = p->op_next) {
  886. X                xfputs(p->op_arg, n);
  887. X#ifndef    SANEEFS
  888. X#define apath(x) x
  889. X                xfputs(apath(p->op_arg), n);
  890. X#endif
  891. X            }
  892. X            for(p = copyin; p; p = p->op_next) {
  893. X                xfputs(p->op_arg, n);
  894. X#ifndef    SANEEFS
  895. X                xfputs(apath(p->op_arg), n);
  896. X#endif
  897. X            }
  898. X            goto nocopy;
  899. X        }
  900. X        if(copyout) {
  901. X            xfputs("copyout", n);
  902. X            i = 0;
  903. X            for(p = copyout; p; p = p->op_next)
  904. X                i++;
  905. X            fprintf(n, "%d", i);
  906. X            putc('\0', n);
  907. X            for(p = copyout; p; p = p->op_next)
  908. X                xfputs(p->op_arg, n);
  909. X        }
  910. X        if(copyin) {
  911. X            xfputs("copyin", n);
  912. X            i = 0;
  913. X            for(p = copyin; p; p = p->op_next)
  914. X                i++;
  915. X            fprintf(n, "%d", i);
  916. X            putc('\0', n);
  917. X            for(p = copyin; p; p = p->op_next) {
  918. X                xfputs(p->op_arg, n);
  919. X                if((fd = open(p->op_arg, 0)) < 0)
  920. X                    xfputs("-1", n);
  921. X                else {
  922. X                    fstat(fd, &statb);
  923. X                    fprintf(n, "%ld", statb.st_size);
  924. X                    putc('\0', n);
  925. X                    while(1) {
  926. X                        i = read(fd, buf, BUFSIZ);
  927. X                        if(i <= 0)
  928. X                            break;
  929. X                        fwrite(buf, sizeof(char), i, n);
  930. X                    }
  931. X                    close(fd);
  932. X                }
  933. X            }
  934. X        }
  935. X    }
  936. Xnocopy:
  937. X    xfputs("done", n);
  938. X    fflush(n);
  939. X    com(s, se);
  940. X}
  941. X
  942. Xbotch()
  943. X{
  944. X    fprintf(stderr, "Protocol timeout\n");
  945. X    exit(1);
  946. X}
  947. X
  948. Xqconnect(h)
  949. Xchar *h;
  950. X{
  951. X    int s, trys, i;
  952. X    register struct hostent *hp;
  953. X
  954. X    if(!(hp = gethostbyname(h))) {
  955. X        fprintf(stderr, "%s: Unknown host?!?\n", h);
  956. X        return(-1);
  957. X    }
  958. X    trys = 0;
  959. X    i = IPPORT_RESERVED - 1;
  960. Xretry:
  961. X    if((s = rresvport(&i)) < 0) {
  962. X        perror("rresvport");
  963. X        return(-1);
  964. X    }
  965. X    sin.sin_family = hp->h_addrtype;
  966. X    sin.sin_port = sp->s_port;
  967. X    bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
  968. X    if(connect(s, &sin, sizeof(sin))) {
  969. X        close(s);
  970. X        if(trys++ < 5) {
  971. X            sleep(trys);
  972. X            i--;
  973. X            goto retry;
  974. X        }
  975. X        perror("connect");
  976. X        return(-1);
  977. X    }
  978. X    return(s);
  979. X}
  980. END_OF_FILE
  981. if test 6647 -ne `wc -c <'queue.c'`; then
  982.     echo shar: \"'queue.c'\" unpacked with wrong size!
  983. fi
  984. # end of 'queue.c'
  985. fi
  986. if test -f 'queued.5' -a "${1}" != "-c" ; then 
  987.   echo shar: Will not clobber existing file \"'queued.5'\"
  988. else
  989. echo shar: Extracting \"'queued.5'\" \(5413 characters\)
  990. sed "s/^X//" >'queued.5' <<'END_OF_FILE'
  991. X.TH QUEUED 5 "24 May 1989"
  992. X.UC 4
  993. X.SH NAME
  994. Xqueued  \- format of queued configuration files
  995. X.SH SYNOPSIS
  996. Xvi /usr/lib/queued/``program''
  997. X.PP
  998. X.SH DESCRIPTION
  999. XA queued configuration file consists of a series of lines, each beginning
  1000. Xwith a key token.  Tokens are optionally followed by arguments separated
  1001. Xby single spaces.  Deviations from this format are not accepted.  The
  1002. Xfollowing tokens are supported; most have default values, but some are
  1003. Xrequired.
  1004. X.PP
  1005. Xprogram  \- required, specifies the program name and its absolute path.
  1006. X.PP
  1007. Xqueue  \- required, specifies the queue in which this program runs.
  1008. X.PP
  1009. Xhost  \- optional, specifies the host(s) on which to run this program.  If
  1010. Xomitted, or if the host specified is not available, the program will
  1011. Xrun locally.  If the first character of the hostname is ``/'' then it
  1012. Xis taken instead to be the name of a file containing the actual host
  1013. Xname(s).
  1014. X.PP
  1015. Xqmaster  \- optional, specifies a host to maintain a centralized queue
  1016. X.PP
  1017. Xload  \- optional, specifies the lower and upper load thresholds for
  1018. Xload-controlled processes.  By default, no load-control is done.  If
  1019. Xlower and upper thresholds are the same, a process will not be started
  1020. Xuntil the load is lower than the limit, but no further attempt will
  1021. Xbe made to load-control the process.  If the thresholds are different,
  1022. Xthe first (lower) is the load value at which the process will be started
  1023. Xand the second (higher) is the load value at which the process will be
  1024. Xstopped.  All loads are specified in units of CPU/100; a load of
  1025. X2.34 would be written as 234.
  1026. X.PP
  1027. Xminnice  \- optional, specifies a minimum ``nice'' at which to run
  1028. Xthe program.  Default is zero.  A user may increase the nice for his
  1029. Xjobs by setting the QMINNICE environment variable.
  1030. X.PP
  1031. Xmaxcpu  \- optional, specifies the maximum cpu time in seconds that may be
  1032. Xused by any process run by the program.  Default is no limit.  A user may
  1033. Xdecrease the cpu time allowed for his jobs by setting the QMAXCPU environment
  1034. Xvariable.
  1035. X.PP
  1036. Xmaxtime  \- optional, specifies the maximum real time in seconds that
  1037. Xthe program will be allowed to run.  Default is no limit.  A user may
  1038. Xdecrease the real time allowed for his jobs by setting the QMAXTIME
  1039. Xenvironment variable.  The maxtime option is not recommended for use
  1040. Xin conjunction with load control.
  1041. X.PP
  1042. Xmaxrun  \- optional, specifies the maximum number of programs that
  1043. Xmay run at one time, on one host.  Default is one.
  1044. X.PP
  1045. Xmaxperu  \- optional, specifies the maximum number of programs that
  1046. Xmay be enqueued at one time, by one user.  Default is no limit.  This
  1047. Xoption is effective only in conjunction with a qmaster.
  1048. X.PP
  1049. Xmode  \- required, specifies the mode, which may be one of background
  1050. X(for programs that will not need to read standard input), interactive
  1051. X(for programs that may read standard input), or batch (for programs
  1052. Xthat can be run completely detached from the user, with results
  1053. Xmailed back at completion.
  1054. X.PP
  1055. Xnolocal  \- optional, prevents local execution even if no servers
  1056. Xare available.  This option will not override a host specification.
  1057. X.PP
  1058. Xefs  \- optional, allows an extended file system, if available, to
  1059. Xreplace the normal file copying operation.
  1060. X.PP
  1061. Xrestart  \- optional, indicates that this job should be restarted
  1062. Xafter a system crash.
  1063. X.PP
  1064. Xcopyin  \- optional, specifies a file that must be transported to
  1065. Xthe machine on which the program is executed either by copying or
  1066. Xby use of an extended file system.  Only one file name argument
  1067. Xis allowed, but there may be any number of copyin lines in each
  1068. Xconfiguration file.
  1069. X.PP
  1070. Xcopyout  \- optional, specifies a file that must be transported back
  1071. Xfrom the machine on which the program is executed by use of an
  1072. Xextended file system.  Only one file name argument is allowed, but there
  1073. Xmay be any number of copyout lines in each configuration file.  Note
  1074. Xthat if no extended file system is available, use of copyout is
  1075. Xsomewhat restricted.
  1076. X.PP
  1077. Xoption  \- optional, specifies an option to the program and possible
  1078. Xactions that should be taken when that option is encountered.  In its
  1079. Xsimplest form, option takes a single argument which is the name of
  1080. Xthe option to be ignored.  A trailing asterisk in the option name
  1081. Xserves as a simple wild-card.  An option name of ``DEFAULT'' will
  1082. Xmatch any option which cannot otherwise be matched.  Any of these
  1083. Xforms may be followed by a copyin or copyout statement which
  1084. Xbehaves as described above, but conditionalized on the presence
  1085. Xof the specified option.  Finally, when used in this way, copyin
  1086. Xand copyout may specify the magic tokens ARG0 and ARG1 instead
  1087. Xof file names.  These indicate, respectively, that the file to be
  1088. Xtransported is the option itself or the argument immediately following
  1089. Xit.
  1090. X.SH "FILES (/usr/lib/queued/)"
  1091. XQUEUES        list of active, local queues
  1092. X.br
  1093. X``program''    configuration file for ``program''
  1094. X.SH "FILES (/usr/spool/queued/)"
  1095. XLOCK            master lock node
  1096. X.br
  1097. X``queue''        current information for ``queue''
  1098. X.br
  1099. X``queue''.lock    lock on ``queue''
  1100. X.br
  1101. X``queue''.tmp    used for rewriting ``queue''
  1102. X.br
  1103. X``pid''        current information for ``pid''
  1104. X.br
  1105. X``pid''.dir    temporary execution directory
  1106. X.br
  1107. X``pid''.batch    output of batch execution process
  1108. X.SH "FILES (Other)"
  1109. X/usr/adm/qacct    queue accounting file
  1110. X.br
  1111. X/etc/hosts.efs    hosts with extended file system
  1112. X.br
  1113. X/etc/hosts.flat    hosts with one-to-one uid mapping
  1114. X.SH "SEE ALSO"
  1115. Xqrm(1), qs(1), queue(1), queued(8)
  1116. X.SH AUTHOR
  1117. XDan Lanciani
  1118. END_OF_FILE
  1119. if test 5413 -ne `wc -c <'queued.5'`; then
  1120.     echo shar: \"'queued.5'\" unpacked with wrong size!
  1121. fi
  1122. # end of 'queued.5'
  1123. fi
  1124. if test -f 'queued.c' -a "${1}" != "-c" ; then 
  1125.   echo shar: Will not clobber existing file \"'queued.c'\"
  1126. else
  1127. echo shar: Extracting \"'queued.c'\" \(5767 characters\)
  1128. sed "s/^X//" >'queued.c' <<'END_OF_FILE'
  1129. X/* Copyright 1990  The President and Fellows of Harvard University
  1130. X
  1131. XPermission to use, copy, modify, and distribute this program for any
  1132. Xpurpose and without fee is hereby granted, provided that this
  1133. Xcopyright and permission notice appear on all copies and supporting
  1134. Xdocumentation, the name of Harvard University not be used in advertising
  1135. Xor publicity pertaining to distribution of the program, or to results
  1136. Xderived from its use, without specific prior written permission, and notice
  1137. Xbe given in supporting documentation that copying and distribution is by
  1138. Xpermission of Harvard University.  Harvard University makes no
  1139. Xrepresentations about the suitability of this software for any purpose.
  1140. XIt is provided "as is" without express or implied warranty.    */
  1141. X
  1142. X
  1143. X/* queued.c - Dan Lanciani '85 */
  1144. X
  1145. X#include <stdio.h>
  1146. X#include <sys/types.h>
  1147. X#include <sys/socket.h>
  1148. X#include <sys/wait.h>
  1149. X#include <netinet/in.h>
  1150. X#include <netdb.h>
  1151. X#include <errno.h>
  1152. X#include <signal.h>
  1153. X#include <sgtty.h>
  1154. X
  1155. X#include "queue.h"
  1156. X
  1157. Xstruct sockaddr_in sin = { AF_INET };
  1158. Xextern int errno;
  1159. Xint reapchild();
  1160. X
  1161. Xmain(argc, argv, envp)
  1162. Xchar **argv, **envp;
  1163. X{
  1164. X    struct servent *sp;
  1165. X    int s, on = 1;
  1166. X    char buf[BUFSIZ], tbuf[BUFSIZ];
  1167. X    FILE *n, *m;
  1168. X
  1169. X#ifndef DEBUG
  1170. X    for(s = 0; s < 30; s++)
  1171. X        close(s);
  1172. X    if((s = open("/dev/tty", 2)) >= 0) {
  1173. X        ioctl(s, TIOCNOTTY, 0);
  1174. X        close(s);
  1175. X    }
  1176. X    if((s = open("/dev/console", 2)) >= 0) {
  1177. X        close(s);
  1178. X        setpgrp(0, 0);
  1179. X    }
  1180. X    s = open("/", 0);
  1181. X    dup(s);
  1182. X    dup(s);
  1183. X    signal(SIGALRM, SIG_IGN);
  1184. X    signal(SIGPIPE, SIG_IGN);
  1185. X    if(fork())
  1186. X        exit(0);
  1187. X#endif
  1188. X
  1189. X    if(!(sp = getservbyname("queue", "tcp"))) {
  1190. X        fprintf(stderr, "queue: Bad service?!?\n");
  1191. X        exit(1);
  1192. X    }
  1193. X    if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  1194. X        perror("socket");
  1195. X        exit(1);
  1196. X    }
  1197. X    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  1198. X    setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
  1199. X    sin.sin_port = sp->s_port;
  1200. X    if(bind(s, &sin, sizeof(sin))) {
  1201. X        perror("bind");
  1202. X        exit(1);
  1203. X    }
  1204. X    listen(s, 10);
  1205. X    if(n = fopen(QUEUES, "r")) {
  1206. X        while(fgets(buf, sizeof(buf), n)) {
  1207. X            buf[strlen(buf)-1] = '\0';
  1208. X            sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
  1209. X            if(m = fopen(tbuf, "r")) {
  1210. X                unlink(tbuf);
  1211. X                creat(tbuf, 0644);
  1212. X                while(fgets(buf, sizeof(buf), m)) {
  1213. X                    buf[strlen(buf)-1] = '\0';
  1214. X                    if(!fork()) {
  1215. X                        close(s);
  1216. X                        fclose(m);
  1217. X                        fclose(n);
  1218. X                        recover(buf);
  1219. X                        exit(0);
  1220. X                    }
  1221. X                }
  1222. X                fclose(m);
  1223. X            }
  1224. X            else
  1225. X                creat(tbuf, 0644);
  1226. X        }
  1227. X        fclose(n);
  1228. X    }
  1229. X    while(1) {
  1230. X        struct sockaddr_in from;
  1231. X        int pid, s0, fromlen;
  1232. X        signal(SIGCHLD, reapchild);
  1233. X        fromlen = sizeof(from);
  1234. X        if((s0 = accept(s, &from, &fromlen)) < 0) {
  1235. X            if(errno = EINTR)
  1236. X                continue;
  1237. X            perror("accept");
  1238. X            exit(1);
  1239. X        }
  1240. X        if(from.sin_family != AF_INET ||
  1241. X            htons((u_short)from.sin_port) >= IPPORT_RESERVED ||
  1242. X            htons((u_short)from.sin_port) < IPPORT_RESERVED / 2) {
  1243. X            close(s0);
  1244. X            continue;
  1245. X        }
  1246. X        if((pid = fork()) < 0) {
  1247. X            perror("fork");
  1248. X            exit(1);
  1249. X        }
  1250. X        if(!pid) {
  1251. X            signal(SIGCHLD, SIG_DFL);
  1252. X            signal(SIGALRM, SIG_DFL);
  1253. X            signal(SIGPIPE, SIG_DFL);
  1254. X            close(s);
  1255. X            doit(s0, &from);
  1256. X            exit(0);
  1257. X        }
  1258. X        close(s0);
  1259. X    }
  1260. X}
  1261. X
  1262. Xreapchild()
  1263. X{
  1264. X    union wait status;
  1265. X    char buf[BUFSIZ], name1[BUFSIZ], name2[BUFSIZ];
  1266. X    FILE *n, *m;    
  1267. X    register int pid, i;
  1268. X    long unid;
  1269. X
  1270. X    while((pid = wait3(&status, WNOHANG, 0)) > 0) {
  1271. X        sprintf(buf, "%s/%d", SPOOLDIR, pid);
  1272. X        if(n = fopen(buf, "r")) {
  1273. X            unlink(buf);
  1274. X            fgetstr(n, buf);
  1275. X            fgetstr(n, buf);
  1276. X            unid = atol(buf);
  1277. X            fgetstr(n, buf);
  1278. X            fgetstr(n, buf);
  1279. X            fclose(n);
  1280. X            if(!fork()) {
  1281. X                signal(SIGCHLD, SIG_DFL);
  1282. X                for(i = 0; i < 30; i++)
  1283. X                    close(i);
  1284. X                if(readconf(buf))
  1285. X                    exit(1);
  1286. X                if(unid) {
  1287. X                    sprintf(buf, "%s/%ld", SPOOLDIR, unid);
  1288. X                    unlink(buf);
  1289. X                }
  1290. X                sprintf(buf, "%s/%d.dir", SPOOLDIR, pid);
  1291. X                if(!access(buf, 0)) {
  1292. X                    if(!vfork()) {
  1293. X                    execl("/bin/rm", "rm", "-rf", buf, 0);
  1294. X                        exit(1);
  1295. X                    }
  1296. X                    wait(0);
  1297. X                }
  1298. X                sprintf(buf, "%s/%d.batch", SPOOLDIR, pid);
  1299. X                unlink(buf);
  1300. X                sprintf(buf, "%s/%d.ebatch", SPOOLDIR, pid);
  1301. X                unlink(buf);
  1302. X                sprintf(name1, "%s/%s", SPOOLDIR, queue);
  1303. X                lock(name1);
  1304. X                n = fopen(name1, "r");
  1305. X                strcpy(name2, name1);
  1306. X                strcat(name2, ".tmp");
  1307. X                m = fopen(name2, "w");
  1308. X                i = 0;
  1309. X                while(fgets(buf, sizeof(buf), n))
  1310. X                    if(atoi(buf) != pid) {
  1311. X                        if(i++ < maxrun)
  1312. X                        kill(atoi(buf), SIGALRM);
  1313. X                        fputs(buf, m);
  1314. X                    }
  1315. X                fclose(m);
  1316. X                fclose(n);
  1317. X                unlink(name1);
  1318. X                link(name2, name1);
  1319. X                unlink(name2);
  1320. X                unlock(name1);
  1321. X                exit(0);
  1322. X            }
  1323. X        }
  1324. X    }
  1325. X}
  1326. X
  1327. Xdoit(s, sin)
  1328. Xstruct sockaddr_in *sin;
  1329. X{
  1330. X    struct hostent *hp;
  1331. X    char buf[BUFSIZ];
  1332. X
  1333. X    if(!(hp=gethostbyaddr(&sin->sin_addr, sizeof(struct in_addr), AF_INET)))
  1334. X        exit(1);
  1335. X    if(index(hp->h_name, '.'))
  1336. X        *index(hp->h_name, '.') = '\0';
  1337. X    gethostname(buf, BUFSIZ);
  1338. X    if(!strcmp(hp->h_name, "localhost")) {
  1339. X        qservice(s, buf, sin, 1);
  1340. X        exit(0);
  1341. X    }
  1342. X    if(!strcmp(hp->h_name, buf)) {
  1343. X        qservice(s, buf, sin, 1);
  1344. X        exit(0);
  1345. X    }
  1346. X    if(infile(EQUIVFILE, hp->h_name)) {
  1347. X        qservice(s, hp->h_name, sin, 0);
  1348. X        exit(0);
  1349. X    }
  1350. X    exit(1);
  1351. X}
  1352. X
  1353. Xqservice(s, host, sin, local)
  1354. Xchar *host;
  1355. Xstruct sockaddr_in *sin;
  1356. X{
  1357. X    char request;
  1358. X
  1359. X    if(read(s, &request, 1) != 1)
  1360. X        exit(1);
  1361. X    switch(request&0377) {
  1362. X
  1363. X        case 0:
  1364. X            enqueue(s, host, sin, local, 0);
  1365. X            break;
  1366. X
  1367. X        case 1:
  1368. X            showqueue(s, host, sin, local);
  1369. X            break;
  1370. X
  1371. X        case 2:
  1372. X            dequeue(s, host, sin, local);
  1373. X            break;
  1374. X
  1375. X        default:
  1376. X            exit(1);
  1377. X            break;
  1378. X    }
  1379. X}
  1380. X
  1381. Xrecover(job)
  1382. Xchar *job;
  1383. X{
  1384. X    int s;
  1385. X    char buf1[BUFSIZ], buf2[BUFSIZ];
  1386. X
  1387. X    sprintf(buf2, "%s/%d", SPOOLDIR, atoi(job));
  1388. X    if((s = open(buf2, 0)) < 0)
  1389. X        exit(0);
  1390. X    unlink(buf2);
  1391. X    sprintf(buf1, "%s/%d.dir", SPOOLDIR, getpid());
  1392. X    sprintf(buf2, "%s/%d.dir", SPOOLDIR, atoi(job));
  1393. X    rename(buf2, buf1);
  1394. X    sprintf(buf2, "%s/%d.batch", SPOOLDIR, atoi(job));
  1395. X    unlink(buf2);
  1396. X    sprintf(buf2, "%s/%d.ebatch", SPOOLDIR, atoi(job));
  1397. X    unlink(buf2);
  1398. X    enqueue(s, 0, 0, 0, 1);
  1399. X    exit(1);
  1400. X}
  1401. END_OF_FILE
  1402. if test 5767 -ne `wc -c <'queued.c'`; then
  1403.     echo shar: \"'queued.c'\" unpacked with wrong size!
  1404. fi
  1405. # end of 'queued.c'
  1406. fi
  1407. if test -f 'readconf.c' -a "${1}" != "-c" ; then 
  1408.   echo shar: Will not clobber existing file \"'readconf.c'\"
  1409. else
  1410. echo shar: Extracting \"'readconf.c'\" \(4684 characters\)
  1411. sed "s/^X//" >'readconf.c' <<'END_OF_FILE'
  1412. X/* Copyright 1990  The President and Fellows of Harvard University
  1413. X
  1414. XPermission to use, copy, modify, and distribute this program for any
  1415. Xpurpose and without fee is hereby granted, provided that this
  1416. Xcopyright and permission notice appear on all copies and supporting
  1417. Xdocumentation, the name of Harvard University not be used in advertising
  1418. Xor publicity pertaining to distribution of the program, or to results
  1419. Xderived from its use, without specific prior written permission, and notice
  1420. Xbe given in supporting documentation that copying and distribution is by
  1421. Xpermission of Harvard University.  Harvard University makes no
  1422. Xrepresentations about the suitability of this software for any purpose.
  1423. XIt is provided "as is" without express or implied warranty.    */
  1424. X
  1425. X
  1426. X/* readconf.c - Dan Lanciani '85 */
  1427. X
  1428. X#include <stdio.h>
  1429. X#include "queue.h"
  1430. X
  1431. Xchar prog[BUFSIZ], host[BUFSIZ], qm[BUFSIZ], queue[BUFSIZ];
  1432. Xchar *hosts[MAXHCNT];
  1433. Xint maxcpu, minnice, maxrun, minload, maxload, mode, priv, efs, restart;
  1434. Xint hcnt, maxtime, nolocal, maxperu;
  1435. Xstruct optent *copyin = NULL;
  1436. Xstruct optent *copyout = NULL;
  1437. Xstruct optent *option = NULL;
  1438. X
  1439. Xreadconf(p)
  1440. Xchar *p;
  1441. X{
  1442. X    register FILE *n, *m;
  1443. X    char name[BUFSIZ], buf[BUFSIZ], action[BUFSIZ], arg[BUFSIZ];
  1444. X    register int i;
  1445. X    register struct optent *op;
  1446. X
  1447. X    sprintf(name, "%s/%s", LIBDIR, p);
  1448. X    if(!(n = fopen(name, "r")))
  1449. X        return(-1);
  1450. X    if(fscanf(n, "%s %s %s\n", buf, name, prog) != 3) {
  1451. X        fclose(n);
  1452. X        return(-2);
  1453. X    }
  1454. X    if(strcmp(buf, "program") || strcmp(name, p)) {
  1455. X        fclose(n);
  1456. X        return(-3);
  1457. X    }
  1458. X    gethostname(host, BUFSIZ);
  1459. X    qm[0] = '\0';
  1460. X    strcpy(queue, "test");
  1461. X    maxcpu = 0;
  1462. X    minnice = 0;
  1463. X    maxrun = 1;
  1464. X    minload = maxload = 0;
  1465. X    mode = QM_BACKGROUND;
  1466. X    priv = 0;
  1467. X    efs = 0;
  1468. X    restart = 0;
  1469. X    hcnt = 0;
  1470. X    maxtime = 0;
  1471. X    nolocal = 0;
  1472. X    maxperu = 0;
  1473. X    if(p = getenv("QMAXCPU"))
  1474. X        maxcpu = atoi(p);
  1475. X    if(p = getenv("QMINNICE"))
  1476. X        minnice = atoi(p);
  1477. X    if(p = getenv("QMAXTIME"))
  1478. X        maxtime = atoi(p);
  1479. X    if(minnice < 0)
  1480. X        minnice = 0;
  1481. X    while(fgets(buf, sizeof(buf), n)) {
  1482. X        buf[strlen(buf)-1] = '\0';
  1483. X        if(!strncmp(buf, "copyin ", 7)) {
  1484. X            op = (struct optent *)malloc(sizeof(struct optent));
  1485. X            op->op_action = OPA_COPYIN;
  1486. X            op->op_arg = newstring(buf+7);
  1487. X            op->op_next = copyin;
  1488. X            copyin = op;
  1489. X            continue;
  1490. X        }
  1491. X        if(!strncmp(buf, "copyout ", 8)) {
  1492. X            op = (struct optent *)malloc(sizeof(struct optent));
  1493. X            op->op_action = OPA_COPYOUT;
  1494. X            op->op_arg = newstring(buf+8);
  1495. X            op->op_next = copyout;
  1496. X            copyout = op;
  1497. X            continue;
  1498. X        }
  1499. X        if(!strncmp(buf, "option ", 7)) {
  1500. X            i = sscanf(buf+7, "%s %s %s", name, action, arg);
  1501. X            if(!i)
  1502. X                continue;
  1503. X            op = (struct optent *)malloc(sizeof(struct optent));
  1504. X            op->op_name = newstring(name);
  1505. X            if(i != 3) {
  1506. X                op->op_action = OPA_IGNORE;
  1507. X                op->op_arg = "ARG0";
  1508. X            }
  1509. X            else {
  1510. X                if(!strcmp(action, "copyin"))
  1511. X                    op->op_action = OPA_COPYIN;
  1512. X                else if(!strcmp(action, "copyout"))
  1513. X                    op->op_action = OPA_COPYOUT;
  1514. X                else op->op_action = OPA_IGNORE;
  1515. X                op->op_arg = newstring(arg);
  1516. X            }
  1517. X            op->op_next = option;
  1518. X            option = op;
  1519. X            continue;
  1520. X        }
  1521. X        if(!strncmp(buf, "host ", 5)) {
  1522. X            strcpy(host, buf+5);
  1523. X            if(host[0] == '/' && (m = fopen(host, "r"))) {
  1524. X                while(fgets(host, sizeof(host), m)) {
  1525. X                    host[strlen(host)-1] = '\0';
  1526. X                    if(hcnt < MAXHCNT)
  1527. X                        hosts[hcnt++] = newstring(host);
  1528. X                }
  1529. X                fclose(m);
  1530. X            }
  1531. X            else
  1532. X                if(hcnt < MAXHCNT)
  1533. X                    hosts[hcnt++] = newstring(host);
  1534. X            continue;
  1535. X        }
  1536. X        if(!strncmp(buf, "qmaster ", 8)) {
  1537. X            strcpy(qm, buf+8);
  1538. X            continue;
  1539. X        }
  1540. X        if(!strncmp(buf, "maxcpu ", 7)) {
  1541. X            if((i = atoi(buf+7)) < maxcpu || !maxcpu)
  1542. X                maxcpu = i;
  1543. X            continue;
  1544. X        }
  1545. X        if(!strncmp(buf, "minnice ", 8)) {
  1546. X            if((i = atoi(buf+8)) > minnice)
  1547. X                minnice = i;
  1548. X            continue;
  1549. X        }
  1550. X        if(!strncmp(buf, "maxtime ", 8)) {
  1551. X            if((i = atoi(buf+8)) < maxtime || !maxtime)
  1552. X                maxtime = i;
  1553. X            continue;
  1554. X        }
  1555. X        if(!strncmp(buf, "maxrun ", 7)) {
  1556. X            maxrun = atoi(buf+7);
  1557. X            continue;
  1558. X        }
  1559. X        if(!strncmp(buf, "load ", 5)) {
  1560. X            sscanf(buf+5, "%d %d", &minload, &maxload);
  1561. X            continue;
  1562. X        }
  1563. X        if(!strncmp(buf, "mode ", 5)) {
  1564. X            if(!strcmp(buf+5, "batch"))
  1565. X                mode = QM_BATCH;
  1566. X            else if(!strcmp(buf+5, "background"))
  1567. X                mode = QM_BACKGROUND;
  1568. X            else if(!strcmp(buf+5, "interactive"))
  1569. X                mode = QM_INTERACTIVE;
  1570. X            continue;
  1571. X        }
  1572. X        if(!strncmp(buf, "queue ", 6)) {
  1573. X            strcpy(queue, buf+6);
  1574. X            continue;
  1575. X        }
  1576. X        if(!strcmp(buf, "magic")) {
  1577. X            priv = 1;
  1578. X            continue;
  1579. X        }
  1580. X        if(!strcmp(buf, "efs")) {
  1581. X            efs = 1;
  1582. X            continue;
  1583. X        }
  1584. X        if(!strcmp(buf, "restart")) {
  1585. X            restart = 1;
  1586. X            continue;
  1587. X        }
  1588. X        if(!strcmp(buf, "nolocal")) {
  1589. X            nolocal = 1;
  1590. X            continue;
  1591. X        }
  1592. X        if(!strncmp(buf, "maxperu ", 8)) {
  1593. X            maxperu = atoi(buf+8);
  1594. X            continue;
  1595. X        }
  1596. X    }
  1597. X    fclose(n);
  1598. X    if(!hcnt)
  1599. X        hosts[hcnt++] = newstring(host);
  1600. X    hosts[hcnt] = 0;
  1601. X    return(0);
  1602. X}
  1603. END_OF_FILE
  1604. if test 4684 -ne `wc -c <'readconf.c'`; then
  1605.     echo shar: \"'readconf.c'\" unpacked with wrong size!
  1606. fi
  1607. # end of 'readconf.c'
  1608. fi
  1609. if test -f 'selhost.c' -a "${1}" != "-c" ; then 
  1610.   echo shar: Will not clobber existing file \"'selhost.c'\"
  1611. else
  1612. echo shar: Extracting \"'selhost.c'\" \(3654 characters\)
  1613. sed "s/^X//" >'selhost.c' <<'END_OF_FILE'
  1614. X/* Copyright 1990  The President and Fellows of Harvard University
  1615. X
  1616. XPermission to use, copy, modify, and distribute this program for any
  1617. Xpurpose and without fee is hereby granted, provided that this
  1618. Xcopyright and permission notice appear on all copies and supporting
  1619. Xdocumentation, the name of Harvard University not be used in advertising
  1620. Xor publicity pertaining to distribution of the program, or to results
  1621. Xderived from its use, without specific prior written permission, and notice
  1622. Xbe given in supporting documentation that copying and distribution is by
  1623. Xpermission of Harvard University.  Harvard University makes no
  1624. Xrepresentations about the suitability of this software for any purpose.
  1625. XIt is provided "as is" without express or implied warranty.    */
  1626. X
  1627. X
  1628. X/* selhost.c - Dan Lanciani '85 '89 */
  1629. X
  1630. X#include <sys/types.h>
  1631. X#include <sys/socket.h>
  1632. X#include <netinet/in.h>
  1633. X#include <stdio.h>
  1634. X#include <netdb.h>
  1635. X#include <signal.h>
  1636. X#include <setjmp.h>
  1637. X#include <pwd.h>
  1638. X#include "queue.h"
  1639. X
  1640. Xextern struct servent *sp;
  1641. Xextern struct passwd *pw;
  1642. Xextern long unid;
  1643. Xextern int tolduser;
  1644. Xstatic jmp_buf jb;
  1645. X
  1646. Xstatic struct ht {
  1647. X    char *ht_name;
  1648. X    int ht_load;
  1649. X} ht[MAXHCNT];
  1650. X
  1651. Xstatic
  1652. Xcmp(a, b)
  1653. Xstruct ht *a, *b;
  1654. X{
  1655. X    return(a->ht_load - b->ht_load);
  1656. X}
  1657. X
  1658. Xstatic
  1659. Xcatch()
  1660. X{
  1661. X    longjmp(jb, 1);
  1662. X}
  1663. X
  1664. Xstatic char *
  1665. Xngetstr(n, buf)
  1666. Xchar *buf;
  1667. X{
  1668. X    register char *p = buf;
  1669. X
  1670. X    do
  1671. X        if(read(n, p, 1) != 1)
  1672. X            return(0);
  1673. X    while(*p++);
  1674. X    return(buf);
  1675. X}
  1676. X
  1677. Xstatic char *argv0;
  1678. X
  1679. Xstatic
  1680. Xdoqrm()
  1681. X{
  1682. X    char buf[20];
  1683. X
  1684. X    if(argv0 && unid) {
  1685. X        sprintf(buf, "%ld", unid);
  1686. X        execl("/usr/local/bin/qrm", "qrm", argv0, buf, 0);
  1687. X    }
  1688. X    exit(-1);
  1689. X}
  1690. X
  1691. Xselhost(argc, argv)
  1692. Xchar **argv;
  1693. X{
  1694. X    register int i, s, u;
  1695. X    int sz;
  1696. X    unsigned char buf[BUFSIZ];
  1697. X    struct sockaddr_in sin;
  1698. X
  1699. X    argv0 = argv[0];
  1700. X    if(hcnt < 2 && !*qm)
  1701. X        return;
  1702. X    for(i = 0; i < hcnt; i++) {
  1703. X        ht[i].ht_name = hosts[i];
  1704. X        ht[i].ht_load = getrload(hosts[i]);
  1705. X    }
  1706. X    qsort((char *)ht, hcnt, sizeof(ht[0]), cmp);
  1707. X    for(i = 0; i < hcnt; i++)
  1708. X        hosts[i] = ht[i].ht_name;
  1709. X    if(!*qm || !(sp = getservbyname("qmaster", "tcp")) ||(s=qconnect(qm))<0)
  1710. X        return;
  1711. X    if((u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  1712. X        perror("socket");
  1713. X        close(s);
  1714. X        return;
  1715. X    }
  1716. X    bzero(&sin, sizeof(sin));
  1717. X    if(bind(u, &sin, sizeof(sin))) {
  1718. X        perror("bind");
  1719. X        close(u);
  1720. X        close(s);
  1721. X        return;
  1722. X    }
  1723. X    sz = sizeof(sin);
  1724. X    if(getsockname(u, &sin, &sz)) {
  1725. X        perror("getsockname");
  1726. X        close(u);
  1727. X        close(s);
  1728. X        return;
  1729. X    }
  1730. X    if(setjmp(jb)) {
  1731. X    out:
  1732. X        alarm(0);
  1733. X        signal(SIGALRM, SIG_DFL);
  1734. X        close(u);
  1735. X        if(s >= 0)
  1736. X            close(s);
  1737. X        signal(SIGPIPE, SIG_DFL);
  1738. X        return;
  1739. X    }
  1740. X    signal(SIGALRM, catch);
  1741. X    alarm(5*60);
  1742. X    signal(SIGPIPE, SIG_IGN);
  1743. X    *buf = 0;
  1744. X    sprintf(buf + 1, "%d", sin.sin_port);
  1745. X    write(s, buf, strlen(buf + 1) + 2);
  1746. X    write(s, argv0, strlen(argv0) + 1);
  1747. X    write(s, pw->pw_name, strlen(pw->pw_name) + 1);
  1748. X    signal(SIGPIPE, SIG_DFL);
  1749. X    if(read(s, buf, 1) != 1)
  1750. X        goto out;
  1751. X    i = *buf;
  1752. X    if(!ngetstr(s, buf))
  1753. X        goto out;
  1754. X    if(i == 1) {
  1755. X        fprintf(stderr, "%s\n", buf);
  1756. X        exit(1);
  1757. X    }
  1758. X    unid = atol(buf);
  1759. X    if(!isunid(unid)) {
  1760. X        unid = 0;
  1761. X        goto out;
  1762. X    }
  1763. X    close(s);
  1764. X    s = -1;
  1765. X    alarm(0);
  1766. X    if(mode == QM_BATCH) {
  1767. X        tolduser++;
  1768. X        if(fork()) {
  1769. X            fprintf(stderr, "Job queued.\n");
  1770. X            exit(0);
  1771. X        }
  1772. X    }
  1773. X    signal(SIGINT, doqrm);
  1774. X    alarm(5*60);
  1775. X    while(1) {
  1776. X        sz = sizeof(sin);
  1777. X        if(recvfrom(u, buf, sizeof(buf), 0, &sin, &sz) <= 0) {
  1778. X            i = alarm(0);
  1779. X            sleep(10);
  1780. X            alarm(i);
  1781. X            continue;
  1782. X        }
  1783. X        switch(*buf) {
  1784. X            case 0:
  1785. X                alarm(5*60);
  1786. X                continue;
  1787. X            case 1:
  1788. X                alarm(0);
  1789. X                signal(SIGALRM, SIG_DFL);
  1790. X                close(u);
  1791. X                i = hcnt;
  1792. X                if(i == MAXHCNT)
  1793. X                    i--;
  1794. X                while(i) {
  1795. X                    hosts[i] = hosts[i - 1];
  1796. X                    i--;
  1797. X                }
  1798. X                hosts[0] = newstring(buf + 1);
  1799. X                return;
  1800. X            case 2:
  1801. X                exit(0);
  1802. X            default:
  1803. X                goto out;
  1804. X        }
  1805. X    }
  1806. X}
  1807. END_OF_FILE
  1808. if test 3654 -ne `wc -c <'selhost.c'`; then
  1809.     echo shar: \"'selhost.c'\" unpacked with wrong size!
  1810. fi
  1811. # end of 'selhost.c'
  1812. fi
  1813. if test -f 'showqueue.c' -a "${1}" != "-c" ; then 
  1814.   echo shar: Will not clobber existing file \"'showqueue.c'\"
  1815. else
  1816. echo shar: Extracting \"'showqueue.c'\" \(2471 characters\)
  1817. sed "s/^X//" >'showqueue.c' <<'END_OF_FILE'
  1818. X/* Copyright 1990  The President and Fellows of Harvard University
  1819. X
  1820. XPermission to use, copy, modify, and distribute this program for any
  1821. Xpurpose and without fee is hereby granted, provided that this
  1822. Xcopyright and permission notice appear on all copies and supporting
  1823. Xdocumentation, the name of Harvard University not be used in advertising
  1824. Xor publicity pertaining to distribution of the program, or to results
  1825. Xderived from its use, without specific prior written permission, and notice
  1826. Xbe given in supporting documentation that copying and distribution is by
  1827. Xpermission of Harvard University.  Harvard University makes no
  1828. Xrepresentations about the suitability of this software for any purpose.
  1829. XIt is provided "as is" without express or implied warranty.    */
  1830. X
  1831. X
  1832. X/* showqueue.c - Dan Lanciani '85 */
  1833. X
  1834. X#include <stdio.h>
  1835. X#include <sys/types.h>
  1836. X#include <sys/stat.h>
  1837. X
  1838. X#include "queue.h"
  1839. X
  1840. Xshowqueue(s)
  1841. X{
  1842. X    struct stat statb;
  1843. X    char buf[BUFSIZ], tbuf[BUFSIZ], lhost[BUFSIZ];
  1844. X    register FILE *n, *m, *l;
  1845. X    register int i, c, oneonly = 0;
  1846. X
  1847. X    gethostname(lhost, BUFSIZ);
  1848. X    for(i = 0; i < 3; i++)
  1849. X        dup2(s, i);
  1850. X    getstr(s, buf);
  1851. X    if(s > 2)
  1852. X        close(s);
  1853. X    if(*buf) {
  1854. X        oneonly++;
  1855. X        goto onlyone;
  1856. X    }
  1857. X    if(!(n = fopen(QUEUES, "r"))) {
  1858. X        fprintf(stderr, "No QUEUES file\n");
  1859. X        exit(1);
  1860. X    }
  1861. X
  1862. X    while(fgets(buf, sizeof(buf), n)) {
  1863. X        buf[strlen(buf)-1] = '\0';
  1864. X    onlyone:
  1865. X        printf("Queue: %s, Host: %s\n", buf, lhost);
  1866. X        sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
  1867. X        if(m = fopen(tbuf, "r")) {
  1868. X            printf("Pid\t\tState\tUser\tHost\tCommand\n");
  1869. X            while(fgets(buf, sizeof(buf), m)) {
  1870. X                buf[strlen(buf)-1] = '\0';
  1871. X                i = atoi(buf);
  1872. X                sprintf(tbuf, "%s/%s", SPOOLDIR, buf);
  1873. X                if(l = fopen(tbuf, "r")) {
  1874. X                    fgetstr(l, buf);
  1875. X                    fgetstr(l, buf);
  1876. X                    if(atol(buf))
  1877. X                        printf("%-16ld", atol(buf));
  1878. X                    else
  1879. X                        printf("%-16d", i);
  1880. X                    if(!fstat(fileno(l), &statb) &&
  1881. X                        (statb.st_mode&0111))
  1882. X                        printf("RUN\t");
  1883. X                    else
  1884. X                        printf("WAIT\t");
  1885. X                    fgetstr(l, buf);
  1886. X                    c = atoi(buf);
  1887. X                    for(i = 0; i < c; i++)
  1888. X                        fgetstr(l, buf);
  1889. X                    fgetstr(l, buf);
  1890. X                    printf("%s\t", buf);
  1891. X                    rewind(l);
  1892. X                    fgetstr(l, buf);
  1893. X                    printf("%s\t", buf);
  1894. X                    fgetstr(l, buf);
  1895. X                    fgetstr(l, buf);
  1896. X                    c = atoi(buf);
  1897. X                    for(i = 0; i < c; i++) {
  1898. X                        fgetstr(l, buf);
  1899. X                        printf("%s ", buf);
  1900. X                    }
  1901. X                    fclose(l);
  1902. X                    printf("\n");
  1903. X                }
  1904. X            }
  1905. X            printf("\n");
  1906. X            fclose(m);
  1907. X        }
  1908. X        else
  1909. X            printf("Warning:  File missing\n\n");
  1910. X        fflush(stdout);
  1911. X        if(oneonly)
  1912. X            exit(0);
  1913. X    }
  1914. X    fclose(n);
  1915. X}
  1916. END_OF_FILE
  1917. if test 2471 -ne `wc -c <'showqueue.c'`; then
  1918.     echo shar: \"'showqueue.c'\" unpacked with wrong size!
  1919. fi
  1920. # end of 'showqueue.c'
  1921. fi
  1922. echo shar: End of archive 2 \(of 3\).
  1923. cp /dev/null ark2isdone
  1924. MISSING=""
  1925. for I in 1 2 3 ; do
  1926.     if test ! -f ark${I}isdone ; then
  1927.     MISSING="${MISSING} ${I}"
  1928.     fi
  1929. done
  1930. if test "${MISSING}" = "" ; then
  1931.     echo You have unpacked all 3 archives.
  1932.     rm -f ark[1-9]isdone
  1933. else
  1934.     echo You still need to unpack the following archives:
  1935.     echo "        " ${MISSING}
  1936. fi
  1937. ##  End of shell archive.
  1938. exit 0
  1939. exit 0 # Just in case...
  1940.